﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Text;

namespace Workflows.Components.TextMining.Collapse
{
    /// <summary>
    /// 
    /// </summary>
    public class PersonNameCompensater:ICompensater
    {
        private List<string> _CompositeFieldNames;
        public List<string> CompositeFieldNames
        {
            get { return _CompositeFieldNames; }
            set { this._CompositeFieldNames=value; }
        }

        private bool _CanSwap;
        public bool CanSwap
        {
            get { return _CanSwap; }
            set { _CanSwap=value; }
        }

        private double _CompensateScore;
        public double CompensateScore
        {
            get { return this._CompensateScore; }
            set { this._CompensateScore = value; }
        }

        public double Compensate(
            Dictionary<string, object> values1, 
            Dictionary<string, object> values2)
        {
            if (values1 == null || values2 == null || values1.Count == 0 || values2.Count == 0)
                return 0.0;

            int countNotMatched = 0;
            PersonNameComparer nameComparer=new PersonNameComparer();
            foreach(string fieldName in this.CompositeFieldNames)
            {
                if(values1.ContainsKey(fieldName) && values2.ContainsKey(fieldName))
                {
                    if(this.CanSwap)
                    {
                        string swappedFieldName = string.Empty;
                        double fieldScore =
                            this.GetFieldScoreConsideringSwaps(
                                ref swappedFieldName,
                                null,
                                fieldName,
                                values1,
                                values2,
                                nameComparer,
                                string.Empty);
                        if (fieldScore <= 0)
                            countNotMatched++;
                    }
                    else
                    {
                        object value1 = values1[fieldName];
                        object value2 = values2[fieldName];
                        double fieldScore = nameComparer.Compare(value1, value2, 0, null, string.Empty);
                        if (fieldScore <= 0)
                            countNotMatched++;
                    }
                    
                }
            }
            if(countNotMatched==this.CompositeFieldNames.Count)
                return this._CompensateScore;
            else
                return 0.0;
        }

        public double Compensate(Dictionary<string, double> fieldScores)
        {
            bool foundFieldMatched = false;
            foreach (string fieldName in this.CompositeFieldNames)
            {
                if (fieldScores != null && fieldScores.ContainsKey(fieldName))
                {
                    if (fieldScores[fieldName] > 0)
                    {
                        foundFieldMatched = true;
                        break;
                    }
                }
            }
            if (!foundFieldMatched)
                return this._CompensateScore;
            else
                return 0.0;
        }

        #region swap
        private double GetFieldScoreConsideringSwaps(
            ref string swappableFieldCandidate,
            SqlConnection conn,
            string currentFieldName,
            Dictionary<string, object> values1,
            Dictionary<string, object> values2,
            PersonNameComparer nameComparer,
            string distTblName)
        {
            object fieldValue1a = values1[currentFieldName];
            object fieldValue2a = values2[currentFieldName];
            double fieldScore1 = nameComparer.Compare(
                fieldValue1a, fieldValue2a, 0, conn, distTblName);
            if (fieldScore1 <= 0 && 
                fieldValue1a != null && 
                fieldValue2a != null &&
                fieldValue1a.ToString().Length > 0 && 
                fieldValue2a.ToString().Length > 0)
            {
                foreach (string swappableField in this.CompositeFieldNames)
                {
                    if (swappableField != currentFieldName)
                    {
                        double fieldScore2a =
                            nameComparer.Compare(
                                values1[currentFieldName],
                                values2[swappableField],
                                0, conn, distTblName);

                        if (fieldScore2a > fieldScore1)
                        {
                            fieldScore1 = fieldScore2a;
                            swappableFieldCandidate = swappableField;
                        }
                    }
                }
            }
            return fieldScore1;
        }

        #endregion
    }
}
